#include "SymboleValue.h"
#include <stdlib.h>
#include <typeinfo> 
////////////////////////////////////////////////////////////////////////////////
SymboleValue::SymboleValue(Symbole s) :
	Symbole(s.getChaine()) {
	 if (s == "<ENTIER>") {
             valeur = new ValeurEntiere(atoi(s.getChaine().c_str()));
            defini = true;
	} else if (s == "<CHAINE>") {
            valeur = new ValeurChaine(s.getChaine());
            defini = true;
        } else if (s == "<REEL>") {
            valeur = new ValeurReelle(atof(s.getChaine().c_str()));           
            defini = true;
        } else if (s == "<CARACTERE>") {
            valeur = new ValeurCaractere(s.getChaine().c_str()[0]);           
            defini = true;
        } else {
		valeur = NULL;
		defini = false;
	}
}

////////////////////////////////////////////////////////////////////////////////
void SymboleValue::afficher(unsigned short indentation) {
	Noeud::afficher(indentation);
	cout << "Feuille - Symbole value : " << getChaine() << endl; // on affiche la chaine du symbole
}
////////////////////////////////////////////////////////////////////////////////
Valeur* SymboleValue::getValeur() {
    if(estDefini())
    {
        if (typeid(*valeur)==typeid(ValeurEntiere)) {
            return dynamic_cast <ValeurEntiere*>(valeur);
        }
        else if (typeid(*valeur)==typeid(ValeurReelle)) {
            return dynamic_cast <ValeurReelle*> (valeur);
        }
        else if (typeid(*valeur)==typeid(ValeurChaine)) {
            return dynamic_cast <ValeurChaine*> (valeur);
        }
        else if (typeid(*valeur)==typeid(ValeurCaractere)) {
            return dynamic_cast <ValeurCaractere*> (valeur);
        }
        else
            exit (0); //TODO : exception
    }
    else
    {
        cout << "Variable non initialisée utilisée dans une expression : "<< getChaine() << "." << endl;
        exit(0); //TODO : exception
    }
        
}
////////////////////////////////////////////////////////////////////////////////
void SymboleValue::setValeur(Valeur* val) {
    if (typeid(*val)==typeid(ValeurEntiere)) {      
        valeur = (ValeurEntiere*)val;
    }
    else if (typeid(*val)==typeid(ValeurReelle)) {
        valeur = (ValeurReelle*)val;
    }
    else if (typeid(*val)==typeid(ValeurChaine)) {
        valeur = (ValeurChaine*)val;
    }
    else if (typeid(*val)==typeid(ValeurCaractere)) {
        valeur = (ValeurCaractere*)val;
    }
    else
        exit(0); //TODO : exception
    defini = true;
}
/////////////////////////////////////////////////////////////////////////////////
string SymboleValue::getCpp() {
    
    return this->getChaine();
}
////////////////////////////////////////////////////////////////////////////////
// Attention : cette fonction (operator) n'est pas membre de la classe SymboleValue
ostream & operator <<(ostream & cout, SymboleValue symb) {
	cout << (Symbole) symb << "\t\t - Valeur=";
	if (symb.defini)
        {
            if (typeid(*(symb.valeur))==typeid(ValeurEntiere))
		cout << ((ValeurEntiere*)(symb.valeur))->getValeur() << (symb == "<VARIABLE>" ? "\t: Entier " : "");
            else if (typeid(*(symb.valeur))==typeid(ValeurReelle))
		cout << ((ValeurReelle*)(symb.valeur))->getValeur() << (symb == "<VARIABLE>" ? "\t: Réel" : "");
            else if (typeid(*(symb.valeur))==typeid(ValeurChaine))
                 cout << ((ValeurChaine*)(symb.valeur))->getValeur() << (symb == "<VARIABLE>" ? "\t: Chaîne" : "");       
            else if (typeid(*(symb.valeur))==typeid(ValeurCaractere))
                  cout << ((ValeurCaractere*)(symb.valeur))->getValeur() << (symb == "<VARIABLE>" ? "\t: Caractère" : "");  
            else
                cout << "type indef";
        }
	else
		cout << "indefinie ";
	return cout;
}
